<template>
  <div class="multiple-card-container material-card-container">
    <!-- start 按钮组 -->
    <div class="material-apply-btn">
      <div>
      <el-button
        @click="handleApplyMaterial"
        v-if="allowApplyMaterialOutTask"
        type="primary"
        size="mini"
        plain
      >{{$t('task.detail.components.applyStock')}}</el-button>

      <template v-if="allowCreate">
        <!-- 有出库权限 允许添加并申领 -->
        <el-dropdown v-if="allowApplyMaterialOutTask && !created && !warrantyConfirmation" trigger="click" @command="handleDropdownCommand" >
          <el-button type="primary" size="mini" plain>{{$t('common.form.preview.materialReturn.btn1')}}</el-button>
          <el-dropdown-menu slot="dropdown">
            <el-dropdown-item command="1">{{$t('common.form.preview.materialReturn.btn2')}}</el-dropdown-item>
            <el-tooltip class="item" effect="dark" :content="$t('task.tip.addMaterialTip1')" placement="right-start">
              <el-dropdown-item command="2">{{$t('common.form.preview.materialReturn.btn3')}}</el-dropdown-item>
            </el-tooltip>
          </el-dropdown-menu>
        </el-dropdown>

        <el-button v-else @click="openChooseMaterialDialog" type="primary" size="mini" plain>{{$t('common.form.preview.materialReturn.btn1')}}</el-button>
      </template>
      </div>

      <span class="cur-point mar-l-24" @click="handleSelectColumn">
        {{$t('common.base.choiceCol')}}
        <i class="iconfont icon-fdn-select"></i>
      </span>
    </div>
    <!-- end 按钮组 -->
    
    <!-- start 物料申领列表 -->
    <material-card-list
      ref="materialCardList"
      :data="data"
      :columns="columns"
      :list-loading="materialCardListLoading"
      :allow-edit="allowEdit"
      :allow-delete="allowDelete"
      :card="card"
    />
    <!-- end 物料申领列表 -->

    <!-- start 新增申领弹窗 -->
    <material-apply-dialog
      ref="materialApplyDialog"
      :fields="fields"
      :is-executor="isExecutor"
      :is-synergies="isSynergies"
      :allow-select-warehouse="allowSelectWarehouse"
      :warranty-status="warrantyStatus"
      :warranty-status-data="warrantyStatusData"
      :allow-warranty-change="allowWarrantyChange"
      :card="card"
      :task="task"
      :tags="tags"
      :productTemplate="productTemplate"
    />
    <!-- end 新增申领弹窗 -->

    <!-- start 添加物料弹窗 -->
    <choose-material-dialog
      ref="chooseMaterialDialog"
      :columns="materialColumns"
      :warranty-status="warrantyStatus"
      :warranty-status-data="warrantyStatusData"
      :allow-warranty-change="allowWarrantyChange"
      :productTemplate="productTemplate"
      @submit="addMaterial"
    />
    <!-- end 添加物料弹窗 -->

    <!-- 选择列 -->
    <biz-select-column
      ref="advanced"
      @save="saveColumnStatus"
      mode="project"
    />
  </div>
</template>

<script>
/* api */
import * as TaskApi from '@src/api/TaskApi.ts';
import { filterProducts } from '@src/api/ProductV2Api';
/* components */
import MaterialCardList from './MaterialCardList';
import MaterialApplyDialog from './MaterialApplyDialog.vue';
import ChooseMaterialDialog from '@src/modules/task/editAllot/components/PartSeviceList/components/ChooseMaterialDialog.vue';

/* mixin */
import cardMixin from './../CardMixin.js';
/* util */
import _ from 'lodash';
import { getRootWindow } from '@src/util/dom'
/* enum */

import { TaskEventNameMappingEnum } from '@model/enum/EventNameMappingEnum.ts';

/* model */
import { MATERIAL_LIST_MAX } from '@src/model/const/Number';
import { MATERIAL_LIST_MAX_LENGTH_MESSAGE } from '@src/model/const/Alert';

import { handlerMaterialList } from '@src/modules/task/view/components/materialUtil.js';

const STAGE_LIST_KEY = 'Work_Order_Add_Material_Requisition';

export default {
  name: 'material-card',
  mixins: [cardMixin],
  props: {
    loginUser: {
      type: Object,
      default: () => ({})
    },
    // 是否是工单负责人
    isExecutor: {
      type: Boolean,
      default: false
    },
    // 是否是工单协同人
    isSynergies: {
      type: Boolean,
      default: false
    },
    warrantyStatus: {
      type: Number
    }
  },
  data() {
    return {
      // 物料申领列表数据
      data: [],
      warrantyStatusData: [
        {
          value: 0,
          label: this.$t('common.base.warranty')
        },
        {
          value: 1,
          label: this.$t('common.base.surrender')
        }
      ],
      departmentData: [],
      productTemplate: [],
      columns: [],
      materialCardListLoading: true
    }
  },
  computed: {
    /** 
    * @description 部门
    */
    tags() {
      const tagDetails = this.loginUser?.tagDetails
      if(!tagDetails) return {}
      
      const { id, type } = tagDetails[0] || {}
      return {
        tagId: id,
        tagType: type
      }
    },

    // 隐藏已审批数、申领数量、出库数量，弹窗不需要展示
    fields() {
      let fields = _.cloneDeep(this.card.fields)
      fields = fields.filter(item => item.fieldName !== 'applyNum' && item.fieldName !== 'paasApproveNum' && item.fieldName !== 'usedNum' )
      
      // 工单详情-新增申领、添加物料 是否展示终端销售价和小计
      if(!this.serviceProviderShowPrice) {
        fields = fields.filter(field => field.fieldName !== 'salePrice' && field.fieldName !== 'total')
      }

      return fields
    },
    // 批次号灰度
    isBatchPeriod() {
      const RootWindow = getRootWindow(window)
      return RootWindow.grayAuth?.BATCH_PERIOD
    },
    /** 
    * @description 物料清单列表项
    */
    dynamicsColumns() {
      let fields = this.card.fields.filter(field => field.enabled && !field.isHidden);
      // 工单详情-物料申领 是否展示终端销售价和小计
      if(!this.serviceProviderShowPrice) {
        fields = fields.filter(field => field.fieldName !== 'salePrice' && field.fieldName !== 'total')
      }

      let fixBatchNumber = [];
      if (this.isBatchPeriod) {
        fixBatchNumber = [{
          label: this.$t('common.label.batchNum'),
          displayName: this.$t('common.label.batchNum'),
          formType: 'text',
          field: 'batchNumber',
          fieldName: 'batchNumber',
          isSystem: 1
        }]
      }
      let newFields = [ ...fields, ...fixBatchNumber]

      // 预计数量、小计、操作
      // 右边固定字段
      let rightFix = ['preNum', 'total']

      // 设置物料名称列宽
      newFields.forEach(field => {
        if (field.fieldName == 'name') {
          field.minWidth = '120px';
        }
        if (rightFix.includes(field.fieldName)) {
          field.fixed = 'right';
        }
        field.show = !!field.isSystem
      })

      return newFields;
    },
    /** 
    * @description 选择物料弹窗列表项
    */
    materialColumns() {
      let fields = [
        ...this.fields
      ]

      fields.push({
        displayName: this.$t('common.base.operation'),
        fieldName: 'action',
        minWidth: '60px',
        isFixed: 'right'
      })

      fields.forEach(field => {
        if (field.fieldName == 'name' || field.fieldName == 'warrantyStatus') {
          field.width = '160px';
        } else if (field.fieldName == 'preNum') {
          field.width = '140px';
        }
        else if (field.fieldName == 'snManage') {
          field.width = '110px';
        }
      })

      return fields;
    },
    /** 
    * @description 物料申领附加组件配置
    */
    config() {
      return JSON.parse(this.card.config || '{}');
    },
    /** 
    * @description 允许在工单中发起出库申请
    * 1. 开启了「 允许在工单中发起出库申请 」
    * 2. 且 登录账号是否是被允许使用的角色（工单负责人或协同人）
    */
    allowApplyMaterialOutTask() {
      let { isTaskOutRep, roleList = [] } = this.config;

      // 判断登录账号是否是被允许使用的角色
      let hasAuthRole = (this.isExecutor && roleList.includes('taskPrincipalPerson')) || (this.isSynergies && roleList.includes('taskSynergyPerson'));

      return isTaskOutRep && hasAuthRole;
    },
    /** 
    * @description 允许物料申领时选择仓库
    */
    allowSelectWarehouse() {
      let { selectWarehouse } = this.config
      return selectWarehouse
    },
    /** 
    * @description 允许在添加物料时修改物料质保状态
    */
    allowWarrantyChange() {
      let { warrantyChange, warrantyRoleList = [] } = this.config
      let hasAuthRole = (this.isExecutor && warrantyRoleList.includes('taskPrincipalPerson')) || (this.isSynergies && warrantyRoleList.includes('taskSynergyPerson'));
      return warrantyChange && hasAuthRole
    },
    /** 
    * @description 质保灰度
    * 开启则允许新增并申领
    */
    warrantyConfirmation() {
      const RootWindow = getRootWindow(window);
      return RootWindow.grayAuth?.warrantyConfirmation || false;
    },
    /** 
    * @description 工单处于待指派状态
    * 开启则允许新增并申领
    */
    created() {
      return this.task?.state === 'created'
    },
  },
  methods: {
    openAddonsDialogAuto() {
      if(this.allowCreate && this.allowApplyMaterialOutTask && !this.created && !this.warrantyConfirmation) {
        this.handleDropdownCommand(2)
      }
    },
    /** 
    * @description 查询物料申领列表数据
    */
    async getInventoryByCardId() {
      try {
        const params = {
          cardId: this.card.cardId,
          taskId: this.task.id
        }
        this.materialCardListLoading = true;
        let res = await TaskApi.getInventoryByCardId(params)
        if (!res.success || !res.result) return;

        this.data = handlerMaterialList((res?.result || []), this.columns);

      } catch(err) {
        console.error('material getInventoryByCardId err', err)
      } finally {
        this.materialCardListLoading = false;
      }
    },
    /** 
    * @description 添加物料清单
    */
    addMaterial(data) {

      // 过滤掉空数据
      let selectedData = data.filter(item => item.id);
      if (selectedData.length == 0) return this.$platform.alert(this.$t('task.tip.addMaterialTip2'));

      // 是否超过最大限制
      let isOverLimit = this.data.length + selectedData.length > MATERIAL_LIST_MAX;
      if (isOverLimit) return this.$platform.alert(MATERIAL_LIST_MAX_LENGTH_MESSAGE);

      this.$refs.chooseMaterialDialog.togglePending(true);

      let baseTaskInventories = [];
      selectedData.forEach(item => {
        baseTaskInventories.push({
          taskId: this.task.id,
          taskNo: this.task.taskNo,
          cardId: this.card.cardId,
          relationId: item.id,
          relationName: item.name,
          preNum: item.preNum,
          type: 3,
          warrantyStatus: item.warrantyStatus,
          snManage: item.snManage,
          property: item.property,
          unit: item.unit,
          salePrice: item.salePrice || 0,
          materialSn: item.sn
        })
      })

      TaskApi.addTaskInventory({ baseTaskTypeId: this.task.templateId, baseTaskInventories })
        .then(res => {
          if (res.success) {
            this.$platform.notification({
              type: 'success',
              title: this.$t('common.base.tip.addSuccess'),
            })
            
            this.getInventoryByCardId();
            this.$refs.chooseMaterialDialog.close();

            this.$eventBus.$emit(TaskEventNameMappingEnum.UpdateRecord);
          } else {
            this.$platform.alert(res.message);
            this.$refs.chooseMaterialDialog.togglePending();
          }
        })
        .catch(err => {
          this.$refs.chooseMaterialDialog.togglePending();
        })
    },
    handleDropdownCommand(command) {
      if (command == 1) return this.openChooseMaterialDialog()

      this.openMaterialApplyDialog(false)
    },
    openChooseMaterialDialog() {
      this.$refs.chooseMaterialDialog.open()
    },
    /** 
     * @description 打开申领出库弹窗 
    */
    openMaterialApplyDialog(isOnlyMaterialOut = true, data = [], defaultWarehouseParams) {
      this.$refs.materialApplyDialog.open(isOnlyMaterialOut, data, defaultWarehouseParams)
    },
    handleApplyMaterial() {
      let { multipleSelection = [] } = this.$refs.materialCardList || {}
      if (multipleSelection.length == 0) return this.$platform.alert(this.$t('task.tip.applyMaterialTip1'))
      // let materialIds = []
      
      let multipleSelectionData = multipleSelection.map(item => {

        // materialIds.push(item.relatedId)

        return {
          ...item,
          label: item.name,
          value: item.relatedId,
          availableNum: 0, // 可用库存字段
          warrantyStatusData: this.warrantyStatusData,
          warehouse: {},
          warehouseId: '',
          warehouseData: [],
          warehousePosition: {},
          positionId: '',
          warehousePositionData: [],
          preNumCopy: item.preNum,
          preNum: Number(item.preNum) - Number(item.applyNum)
        }
      })
      // 默认仓库仓位
      // let defaultWarehouseParams = {
      //   warehouseId: this.warehouse?.value || '',
      //   positionId: this.warehousePosition?.value || '',
      //   materialIds
      // }
      this.openMaterialApplyDialog(true, _.cloneDeep(multipleSelectionData))
    },
    // 获取工单下面的产品的产品类型有物料的产品 
    // 写到这儿数据传到子组件吧，子组件多处用到，减少请求
    async fetchProduct() {
      try {
        let { products = [] } = this.task;
        let params = products.map(item => {
          return item.id;
        });
        const res = await filterProducts(params);
        if (!res.success) return;
        this.productTemplate = res.result || [];
      } catch (error) {
        console.error('搜索产品 function catch err', error);
      } finally {
      }
    },
    // 选择列 ======
    // 构建列表
    async buildColumns() {
      // 获取缓存在本地的选择列配置
      const localStorageData = await this.getLocalStorageData();
      const columnStatus = localStorageData.columnStatus || [];

      const localColumns = columnStatus
        .map((i) => (typeof i == 'string' ? { field: i, show: true } : i))
        .reduce((acc, col, currentIndex) => {
          acc[col.field] = {
            field: col,
            index: currentIndex,
          };
          return acc;
        }, {});

      let columnListFields = this.dynamicsColumns; // 本地默认的表格项字段
      if (Array.isArray(columnStatus) && columnStatus.length > 0) {
        // 有本地缓存--列表排序
        columnListFields = this.buildSortFields(columnListFields, localColumns);
      }
      
      const columns = columnListFields.map((col) => {
        // 选择列配置 是否勾选（显示）&宽度
        let show = col.show === true;
        let localField = localColumns[col.fieldName]?.field || null;
        
        if (null != localField) {
          show = localField.show !== false;
        }

        col.show = show;
        return col;
      });
      
      this.columns = [];
      this.$nextTick(() => {
        this.$set(this, 'columns', columns.slice());
      });
    },
    // 选择列排序
    buildSortFields(originFields = [], fieldsMap = {}) {
      let fields = [];
      let unsortedFields = [];

      originFields.forEach((originField) => {
        let { fieldName } = originField;
        let field = fieldsMap[fieldName];

        if (field) {
          let { index } = field;
          fields[index] = originField;
        } else {
          unsortedFields.push(originField);
        }
      });

      // 存储列数据之后，如果存在列被删除的情况，可能产生空值，需要过滤，否则其他地方没做判断会报错
      return fields.filter(v => v).concat(unsortedFields);
    },
    // 点击选择列
    handleSelectColumn() {
      this.columns.forEach(item => {
        item.tableName = 'project'
      })
      this.$refs.advanced.open(this.columns)
    },
    getLocalStorageData() {
      const dataStr = localStorage.getItem(STAGE_LIST_KEY) || '{}'
      return JSON.parse(dataStr)
    },
    saveDataToStorage(key, value) {
      const data = this.getLocalStorageData()
      data[key] = value
      localStorage.setItem(STAGE_LIST_KEY, JSON.stringify(data))
    },
    // 保存选择列配置到本地
    saveColumnStatusToStorage() {
      const localStorageData = this.getLocalStorageData();
      let columnsStatus = null;

      // 判断是否存储选择列
      const columnsList = this.columns.map(c => ({
        field: c.fieldName,
        show: c.show
      }));

      if (localStorageData.columnStatus) {
        localStorageData.columnStatus = columnsList;
        columnsStatus = localStorageData.columnStatus;
      } else {
        columnsStatus = columnsList;
      }

      this.saveDataToStorage('columnStatus', columnsStatus);
    },
    // 保存选择列
    saveColumnStatus(event) {
      let columns = event.data || [];
      this.columns = [];
      this.$nextTick(() => {
        this.$set(this, 'columns', columns.slice());
        this.saveColumnStatusToStorage();
      });
      this.$message.success(this.$t('common.base.saveSuccess'));
    }
  },
  mounted() {
    this.getInventoryByCardId();
    this.fetchProduct();

    this.columns = this.dynamicsColumns;
    this.buildColumns();
  },
  components: {
    [MaterialCardList.name]: MaterialCardList,
    [MaterialApplyDialog.name]: MaterialApplyDialog,
    [ChooseMaterialDialog.name]: ChooseMaterialDialog
  }
}
</script>

<style lang="scss" scoped>
.material-card-container {
  .el-dropdown {
    margin-left: 12px;
  }
  .material-apply-btn {
    display: flex;
    justify-content: space-between;
    padding: 10px 0;
  }
}

</style>